package top.likeqc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.likeqc.dto.PaperDTO;
import top.likeqc.entity.Answer;
import top.likeqc.entity.Paper;
import top.likeqc.entity.Question;
import top.likeqc.entity.SysUser;
import top.likeqc.mapper.PaperMapper;
import top.likeqc.service.IAnswerService;
import top.likeqc.service.IPaperService;
import top.likeqc.service.IQuestionService;
import top.likeqc.util.SecurityUtil;
import top.likeqc.vo.PaperAndQuestionVO;
import top.likeqc.vo.PaperVO;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 问卷 服务实现类
 * </p>
 *
 * @author likeqc
 * @since 2022-04-16
 */
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements IPaperService {
    @Autowired
    PaperMapper paperMapper;

    @Autowired
    IQuestionService questionService;

    @Autowired
    IAnswerService answerService;

    @Autowired
    SecurityUtil securityUtil;

    @Override

    public Page<PaperVO> listByCourseId(Page<PaperVO> page, Long courseId) {

        page = paperMapper.listByCourseId(page, courseId);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addPaperAndQuestion(PaperDTO paperDTO) {
        // 保存问卷
        Paper paper = getPaperByPaperDTO(paperDTO);
        if (paper.getId() != null && paper.getId() > 0) {
            updateById(paper);
        } else {
            save(paper);

            // 保存问题
            List<Question> questionList = getQuestionListByPaperDtoAndPaper(paperDTO, paper);
            questionService.saveBatch(questionList);
        }
        return true;
    }

    private Paper getPaperByPaperDTO(PaperDTO paperDTO) {
        Paper paper = new Paper();

        paper.setId(paperDTO.getId());
        paper.setCourseId(paperDTO.getCourseId());
        paper.setTitle(paperDTO.getTitle());
        paper.setRemark(paperDTO.getRemark());
        paper.setStartDate(paperDTO.getStartDate());
        paper.setStatus(paperDTO.getStatus());

        return paper;
    }

    private List<Question> getQuestionListByPaperDtoAndPaper(PaperDTO paperDTO, Paper paper) {
        List<Question> questionList = new ArrayList<>();

        paperDTO.getQuestionList().forEach(question -> {
            question.setPaperId(paper.getId());
            questionList.add(question);
        });

        return questionList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByCourseId(List<Long> paperIds) {

        List<Question> questionList =
            questionService.list(new QueryWrapper<Question>().in("paper_id", paperIds).select("id"));
        List<Long> questionIds = new ArrayList<>();
        questionList.forEach(question -> questionIds.add(question.getId()));
        // 删除答案
        answerService.remove(new QueryWrapper<Answer>().in("question_id", questionIds));
        // 删除问题
        questionService.remove(new QueryWrapper<Question>().in("paper_id", paperIds));
        // 删除问卷
        removeByIds(paperIds);

        return true;
    }

    @Override
    public PaperAndQuestionVO getPaperAndQuestion(Long paperId) throws Exception {
        SysUser sysUser = securityUtil.getSysUser();

        // 问卷
        Paper paper = getById(paperId);
        cheak(paper, sysUser);
        // 问题
        List<Question> questionList = questionService.list(new QueryWrapper<Question>().eq("paper_id", paperId));

        PaperAndQuestionVO paperAndQuestionVO = getPaperAndQuestionVO(paper, questionList);

        return paperAndQuestionVO;
    }

    @Override
    public Page<PaperVO> getTodoPaper(Page<PaperVO> page) {
        SysUser sysUser = securityUtil.getSysUser();
        page = paperMapper.getTodoPaper(page, sysUser.getId());
        return page;
    }

    @Override
    public Page<PaperVO> getHistoryPaper(Page<PaperVO> page) {
        SysUser sysUser = securityUtil.getSysUser();
        page = paperMapper.getHistoryPaper(page, sysUser.getId());
        return page;
    }

    @Override
    public Page<PaperVO> getFuturePaper(Page<PaperVO> page) {
        SysUser sysUser = securityUtil.getSysUser();
        page = paperMapper.getFuturePaper(page, sysUser.getId());
        return page;
    }


    /**
     * 检测当前用户是否能够获取问卷
     */
    private void cheak(Paper paper, SysUser sysUser) throws Exception {
        if (sysUser.hasRoleAdmin() || sysUser.hasRoleTeacher()) {
            return;
        }
        if (sysUser.hasRoleStudent() && LocalDateTime.now().isAfter(paper.getStartDate())) {
            return;
        }
        //
        throw new Exception("问卷未开放");
    }

    private PaperAndQuestionVO getPaperAndQuestionVO(Paper paper, List<Question> questionList) {
        PaperAndQuestionVO vo = new PaperAndQuestionVO();

        vo.setId(paper.getId());
        vo.setCourseId(paper.getCourseId());
        vo.setTitle(paper.getTitle());
        vo.setRemark(paper.getRemark());
        vo.setStartDate(paper.getStartDate());
        vo.setStatus(paper.getStatus());
        vo.setCode(paper.getCode());
        vo.setQuestionList(questionList);

        return vo;
    }
}
